<!DOCTYPE HTML>
<html>

<head>
	<link rel="bookmark"  type="image/x-icon"  href="/img/logo.png"/>
	<link rel="shortcut icon" href="/img/logo.png">
	
			    <title>
    Archer`s
    </title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <link rel="stylesheet" href="/css/mic_main.css" />
    <link rel="stylesheet" href="/css/dropdownMenu.css" />
    <meta name="keywords" content="Archer,arche2r,Arche2r,Archer的博客" />
    
    	<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
	 
    <noscript>
        <link rel="stylesheet" href="/css/noscript.css" />
    </noscript>
    <style type="text/css">
        body:before {
          content: ' ';
          position: fixed;
          top: 0;
          background: url('/img/bg.jpg') center 0 no-repeat;
          right: 0;
          bottom: 0;
          left: 0;
          background-size: cover; 
        }
    </style>

			    
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script async type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


    <script src="/js/jquery.min.js"></script>
    <script src="/js/jquery.scrollex.min.js"></script>
    <script src="/js/jquery.scrolly.min.js"></script>
    <script src="/js/skel.min.js"></script>
    <script src="/js/util.js"></script>
    <script src="/js/main.js"></script>
	
<meta name="generator" content="Hexo 4.2.0"></head>
    
		
<!-- Layouts -->



<!--  代码渲染  -->
<link rel="stylesheet" href="/css/prism_coy.css" />
<link rel="stylesheet" href="/css/typo.css" />
<!-- 文章页 -->
<body class="is-loading">
    <!-- Wrapper 外包 s-->
    <div id="wrapper" class="fade-in">
        <!-- Intro 头部显示 s -->
        <!-- Intro 头部显示 e -->
        <!-- Header 头部logo start -->
        <header id="header">
    <a href="/" class="logo">IT`S ME</a>
</header>
        <!-- Nav 导航条 start -->
        <nav id="nav" class="special" >
            <ul class="menu links" >
			<!-- Homepage  主页  --> 
			<li >
	            <a href="/" rel="nofollow">主页</a>
	        </li>
			<!-- categories_name  分类   --> 
	        
	        <!-- archives  归档   --> 
	        
	        <li class="active">
	            <a href="#s1">归档</a>
	                    <ul class="submenu">
	                        <li>
	                        <a class="archive-link" href="/archives/2022/01/">一月 2022</a></li><li><a class="archive-link" href="/archives/2020/06/">六月 2020</a></li><li><a class="archive-link" href="/archives/2019/08/">八月 2019</a></li><li><a class="archive-link" href="/archives/2019/06/">六月 2019</a></li><li><a class="archive-link" href="/archives/2019/05/">五月 2019</a>
	                    </ul>
	        </li>
	        
	        
		        <!-- Pages 自定义   -->
		        
		        <li>
		            <a href="/gallery/" title="图库">
		                图库
		            </a>
		        </li>
		        


            </ul>
            <!-- icons 图标   -->
			<ul class="icons">
                    
                    <li>
                        <a title="tv" href="https://space.bilibili.com/39520610" target="_blank" rel="noopener">
                            <i class="icon fa fa-tv"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="github" href="https://github.com/arche2r" target="_blank" rel="noopener">
                            <i class="icon fa fa-github"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="qq" href="tencent://message/?uin=1151147869&Site=&Menu=yes" target="_blank" rel="noopener">
                            <i class="icon fa fa-qq"></i>
                        </a>
                    </li>
                    
			</ul>
</nav>

        <div id="main" >
            <div class ="post_page_title_img" style="height: 25rem;background-image: url(/images/pic/90530/90530.jpg);background-position: center; background-repeat:no-repeat; background-size:cover;-moz-background-size:cover;overflow:hidden;" >
                <a href="#" style="padding: 4rem 4rem 2rem 4rem ;"><h2 >责任链模式之filter实现</h2></a>
            </div>
            <!-- Post -->
            <div class="typo" style="padding: 3rem;">
                <p><strong><a href="https://blog.csdn.net/qian520ao/article/details/73558275" target="_blank" rel="noopener">责任链模式通俗来说就是关联一串能够处理事务的对象，使多个对象都有机会处理请求，从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链传递该请求，直到有对象处理它为止。</a></strong></p>
<p>最常见的的责任链模式,类似于将if…else…分离抽取为不同处理类,也就是if…else…的复杂化模式.</p>
<p>JAVA中对于Filter的处理便是使用了责任链的设计模式,在该模式中,可以灵活定义责任对象的个数和顺序,并且对责任对象和任务进行解耦.提高程序的扩展性.</p>
<p>先上实体类:</p>
<pre><code>/**
 * 普通的处理类A
 */
public class AFil implements Fil {
    @Override
    public void doFil(Req req, Resp resp, FilChain fc) {
//      将请求中的所有A用1来代替
        req.str = req.str.replace(&quot;A&quot;, &quot;1&quot;);
//      放行执行下一个处理类，这里用到了刚才传过来的fc对象，保证从头到尾用的是同一个对象
        fc.doFil(req, resp);
//      最后将处理信息追加到回复中
        resp.str += &quot;_A已处理_&quot;;
    }
}

/**
 * 普通的处理类B,具体同A
 */
class BFil implements Fil {
    @Override
    public void doFil(Req req, Resp resp, FilChain fc) {
        req.str=req.str.replace(&quot;B&quot;,&quot;2&quot;);
        fc.doFil(req,resp);
        resp.str += &quot;_B已处理_&quot;;
    }
}

/**
 * 普通的处理类C,具体同A
 */
class CFil implements Fil {
    @Override
    public void doFil(Req req, Resp resp, FilChain fc) {
        req.str=req.str.replace(&quot;C&quot;,&quot;3&quot;);
        fc.doFil(req,resp);
        resp.str += &quot;_C已处理_&quot;;
    }
}

/**
 * Response对象
 */
class Resp {
    String str;
}

/**
 * Request对象
 */
class Req {
    String str;
}</code></pre><p>然后是filter接口和FilterChain类:</p>
<pre><code>/**
 * 定义接口Filter
 */
public interface Fil {
    /**
     * doFilter方法
     * @param req 传来的请求参数
     * @param resp 发回的返回参数
     * @param fc FilterChain 过滤器链
     */
    void doFil(Req req,Resp resp,FilChain fc);
}

/**
 * 定义过滤器链,由过滤器链中的li和index来定义和执行所有的过滤器
 */
class FilChain{
    //    存储所有的过滤器
    List&lt;Fil&gt; li = new ArrayList&lt;&gt;();
    //    定义当前过滤器的遍历进度
    int index = 0;
    //    开始遍历执行每一个过滤器，先从第0个开始
    public void doFil(Req req, Resp resp) {
//        判断fc不为空且当前遍历的次数少于总过滤器个数
        if (this != null&amp;&amp;this.li.size()&gt;0&amp;&amp;index&lt;li.size()){
//            获取最新一个过滤器
            Fil fil = li.get(index);
//            让过滤器索引更新
            index++;
//            执行最新过滤器
            fil.doFil(req,resp,this);
        }else{
//            这里可以放行到其它地方
        }
    }
    //添加过滤器方法
    public FilChain addFil(Fil f){
        li.add(f);
        return this;
    }
}</code></pre><p>最后是测试类:</p>
<pre><code>/**
 * 测试类
 */
@Slf4j
public class Test {
    public static void main(String[] args) {
//        定义初始数据
        String str = &quot;ABC&quot;;
//        定义请求和回应对象并设置参数，请求参数为’ABC‘，响应参数默认为空
        Req req = new Req();
        req.str = str;
        Resp resp = new Resp();
        resp.str = &quot;&quot;;
//        定义责任链，添加过滤器对象
        FilChain fc = new FilChain();
        fc.addFil(new AFil()).addFil(new BFil()).addFil(new CFil());
//        调用过滤器链的doFilter方法
        fc.doFil(req,resp);
        log.info(req.str);
        log.info(resp.str);
    }
}</code></pre><p>运行结果如图:</p>
<p><img src="/images/pic/90530/90530-1.png" alt="img"></p>
<p>可以看到在整个流程中,消息’ABC’分别经历了三个不同的过滤器并反向添加了三条不同的响应信息,在实际开发过程中,filter的顺序是可以根据@Order注解值的大小来进行定义的,值越小级别越高,或者还可以调整filter在web.xml中的位置.在执行完所有的filter后可以通过else进入Controller或者Servlet来完成进一步处理.</p>

            </div>

            <!-- Post Comments -->
            

        </div>
        <!-- Copyright 版权 start -->
                <div id="copyright">
                <span id="busuanzi_container_site_pv"><span id="busuanzi_value_site_pv"></span>次的回眸</span>
<span>·</span>
				<span id="busuanzi_container_site_pv"> 2022 </span> 

        </div>
    </div>
</body>



 	
</html>
